package online.sh.cn.fy.common.utils;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.servlet.http.Cookie;

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

/**
 * 3DES加密工具类
 * 
 */
public class DES3Util {
	// 密钥
	private final static String SECRETKEY = "btohblkhjejho401fx4604fs";
	// 向量
	private final static String IV = "3267hisc";
	// 加解密统一使用的编码方式
	private final static String encoding = "utf-8";

	private final static String secretKeyhanGO = "nenglikaifang@lx100$#3#$";
	private final static String ivhuanGo = "13579025";

	/**
	 * 3DES加密
	 * 
	 * @param plainText
	 *            普通文本
	 * @return
	 */
	public static String encrypt(String plainText) throws Exception {
		Key deskey = null;
		DESedeKeySpec spec = new DESedeKeySpec(SECRETKEY.getBytes());
		SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
		deskey = keyfactory.generateSecret(spec);

		Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
		IvParameterSpec ips = new IvParameterSpec(IV.getBytes());
		cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
		byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
		return Base64.encode(encryptData);
	}

	/**
	 * 3DES解密
	 * 
	 * @param encryptText
	 *            加密文本
	 * @return
	 */
	public static String decrypt(String encryptText) throws Exception {
		Key deskey = null;
		DESedeKeySpec spec = new DESedeKeySpec(SECRETKEY.getBytes());
		SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
		deskey = keyfactory.generateSecret(spec);
		Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
		IvParameterSpec ips = new IvParameterSpec(IV.getBytes());
		cipher.init(Cipher.DECRYPT_MODE, deskey, ips);

		byte[] decryptData = cipher.doFinal(Base64.decode(encryptText));

		return new String(decryptData, encoding);
	}

	public static String decrypt(String secretKey, String iv, String encryptStr) throws Exception {
		System.out.println("\n\t需要解密的字符串：\t" + encryptStr);
		String plainText = "";
		try {
			// System.out.println("直接解密");
			plainText = DES3Util.decryptString(secretKey, iv, encryptStr);
		} catch (Exception e) {
			System.out.println("解码解密");
			plainText = DES3Util.decryptStringURLDecoder(secretKey, iv, encryptStr);
		}
		System.out.println("\tDES3解密后：" + plainText);
		return plainText;
	}

	/**
	 * 3DES加密
	 * 
	 * @param secretKey
	 *            秘钥
	 * @param iv
	 *            偏移向量
	 * @param plainText
	 *            普通文本
	 * @return
	 * @throws Exception
	 */
	public static String encryptString(String secretKey, String iv, String plainText) throws Exception {
		Key deskey = null;
		DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
		SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
		deskey = keyfactory.generateSecret(spec);

		Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
		IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
		cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
		byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
		return Base64.encode(encryptData);
	}

	/**
	 * 3DES解密
	 * 
	 * @param secretKey
	 *            秘钥
	 * @param iv
	 *            偏移向量
	 * @param encryptText
	 *            密文
	 * @return
	 * @throws Exception
	 */
	public static String decryptString(String secretKey, String iv, String encryptText) throws Exception {
		Key deskey = null;
		DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
		SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
		deskey = keyfactory.generateSecret(spec);
		Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
		IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
		cipher.init(Cipher.DECRYPT_MODE, deskey, ips);

		byte[] decryptData = cipher.doFinal(Base64.decode(encryptText));

		return new String(decryptData, encoding);
	}

	/**
	 * URLDecoder解码_3DES解密
	 * 
	 * @param secretKey
	 *            秘钥
	 * @param iv
	 *            偏移向量
	 * @param encryptText
	 *            密文
	 * @return
	 * @throws Exception
	 */
	public static String decryptStringURLDecoder(String secretKey, String iv, String encryptText) throws Exception {
		String retJsonStr = decryptString(secretKey, iv, URLDecoder.decode(encryptText));
		return retJsonStr;
	}

	/**
	 * URLDecoder解码_3DES解密
	 * 
	 * @param secretKey
	 *            秘钥
	 * @param iv
	 *            偏移向量
	 * @param encryptText
	 *            密文
	 * @return
	 * @throws Exception
	 */
	public static String decryptStringNotURLDecoder(String secretKey, String iv, String encryptText) throws Exception {
		String retJsonStr = decrypt(secretKey, iv, encryptText);
		return retJsonStr;
	}
	
	/**
	 * 3DES加密_URLEncoder编码
	 * 
	 * @param secretKey
	 * @param iv
	 * @param plainText
	 * @return
	 * @throws Exception
	 */
	public static String encryptStringURLEncoder(String secretKey, String iv, String plainText) throws Exception {
		String base64Str = encryptString(secretKey, iv, plainText);
		return URLEncoder.encode(base64Str);
	}

	public static String decryptStringURLDecoder2(String plainText) {
		String str = "";
		try {
			str = decryptStringNotURLDecoder(secretKeyhanGO, ivhuanGo, plainText);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return str;
	}

	public static void main(String[] args) throws Exception {
		 String content = "oSQHvsuFbrFOBFvLaVLsmpGzKkjI";
		 Cookie cook=new Cookie("sss",DES3Util.encrypt(content));
		 System.out.println("加密前长度:" + content.length());
		 System.out.println(cook.getValue());
		 System.out.println(DES3Util.encrypt(content));
		 System.out.println(DES3Util.decrypt("I3q0Fcy2B0r3VhXNHr9u7A=="));
		 System.out.println(DES3Util.encryptString(SECRETKEY, IV, content));
		 System.out.println(DES3Util.decryptString(SECRETKEY, IV, DES3Util.encryptString(SECRETKEY, IV, content)));
	}
}
